<?php

function qfinanceCacher() {
    $path = '../QFinance/';
    $jsPath = '../QFinance/js/';
    $cssPath = '../QFinance/css/';

    echo 'Looking for js and css files...' . PHP_EOL;

    $fileList = CreateFileList($jsPath, array('js'), array(), array('../QFinance/lib/Ext/js' ));
    $fileList = CreateFileList($cssPath, array('css'), array(), array('../QFinance/lib/Ext/css'),$fileList);

    echo 'Ordering files by depedency...' . PHP_EOL;

    $fileList = OrderByDependency($fileList);
    /*
      foreach ($fileList as $file)
      echo $file . PHP_EOL;
     */
    echo 'Creating front-end cache file...' . PHP_EOL;

    foreach ($fileList as &$file) {
        $file = str_replace($path, '', $file);
    }

    if (!file_exists($path .'cache'))
        mkdir($path . 'cache');
    
    $fd = fopen($path . 'cache/qfinancefrontendfilelist.cache', "w");
    fwrite($fd, json_encode($fileList));
    fclose($fd);

    echo 'Looking for php files...' . PHP_EOL;

    $fileList = CreateFileList($path, array('php'), array('../QFinance/index.php'), array());

    echo 'Creating back-end cache file...' . PHP_EOL;

    $backendFileList = array();
    foreach ($fileList as $file) {
        $fileInfo = pathinfo($file);
        $backendFileList[$fileInfo['filename']] = str_replace($path, '', $file);
    }

    $fd = fopen($path . 'cache/qfinancebackendfilelist.cache', "w");
    fwrite($fd, json_encode($backendFileList));
    fclose($fd);
}

function CreateFileList($path, $extension, $filesToExclude = array(), $directoriesToExclude = array(), $fileList = array()) {
    $dirHandler = opendir($path);
    while (false !== ($file = readdir($dirHandler))) {
        if ($file != "." && $file != "..") {
            if (!is_dir($path . $file)) {
                $fileInfo = pathinfo($path . $file);
                if (in_array($fileInfo['extension'], $extension) && !in_array($path . $file, $filesToExclude)) {
                    $fileList[] = $path . $file;
                }
            } else {
                if (!in_array($path . $file . '/', $directoriesToExclude))
                    $fileList = CreateFileList($path . $file . '/', $extension, $filesToExclude, $directoriesToExclude, $fileList);
            }
        }
    }
    closedir($dirHandler);
    return $fileList;
}

function readFileDependency($file) {
    $dependencies = array();

    $fileContent = file_get_contents($file);
    $startPos = strpos($fileContent, '@depends');
    if ($startPos > 0) {
        $pos = array();
        $endPos = strpos($fileContent, chr(13) + chr(10), $startPos + 9);
        if ($endPos)
            $pos[] = $endPos;
        $endPos = strpos($fileContent, chr(13), $startPos + 9);
        if ($endPos)
            $pos[] = $endPos;
        $endPos = strpos($fileContent, chr(10), $startPos + 9);
        if ($endPos)
            $pos[] = $endPos;
        if (sizeof($pos) > 0)
            $endPos = min($pos);
        else
            $endPos = false;
        if ($endPos) {
            $depends = substr($fileContent, $startPos + 9, ($endPos - $startPos - 9));
            $dependencies = explode(',', $depends);
        }
    }

    foreach ($dependencies as &$dependency) {
        $dependency = trim($dependency);
    }
    return $dependencies;
}

function OrderByDependency($fileList) {
    do {
        $changed = false;
        for ($i = 0; $i < sizeof($fileList); $i++) {
            $iDependency = readFileDependency($fileList[$i]);
            $analisedFile = $fileList[$i];

            // Se depender de todos os outros
            if (in_array('*', $iDependency)) {
                // Verifica se os pr�ximos tamb�m s�o *
                $ok = true;
                for ($n = $i + 1; $n < sizeof($fileList); $n++) {
                    $nDependency = readFileDependency($fileList[$n]);
                    if (!in_array('*', $nDependency))
                        $ok = false;

                    if (!$ok)
                        break;
                }
                if (!$ok) {
                    $temp = $fileList[$i];
                    $fileList = array_remove($fileList, $i);
                    $fileList = array_insert($fileList, sizeof($fileList), $temp);
                    $changed = true;
                    break;
                }
            }

            // Procura a posi��o da �ltima dependencia
            $pos = 0;
            for ($n = 0; $n < sizeof($fileList); $n++) {
                $fileInfo = pathinfo($fileList[$n]);
                $fileName = $fileInfo['filename'] . '.' . $fileInfo['extension'];
                if (in_array($fileName, $iDependency))
                    $pos = $n;
            }

            // Se encontrou dependencia e a dependencia est� depois da posi��o do elemento dependente, move ele
            if ($pos > $i) {
                $temp = $fileList[$i];
                $fileList = array_remove($fileList, $i);
                $fileList = array_insert($fileList, $pos, $temp);
                $changed = true;
                break;
            }
        }
    } while ($changed);

    return $fileList;
}

?>